<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content=
    "application/xhtml+xml; charset=iso-8859-1" />
    <title>
      About initramfs
    </title>
    <link rel="stylesheet" type="text/css" href="../stylesheets/lfs.css" />
    <meta name="generator" content="DocBook XSL Stylesheets V1.78.1" />
    <link rel="stylesheet" href="../stylesheets/lfs-print.css" type=
    "text/css" media="print" />
  </head>
  <body class="blfs" id="blfs-2020-04-02">
    <div class="navheader">
      <h4>
        Beyond Linux<sup>�</sup> From Scratch <span class="phrase">(System
        V</span> Edition) - Version 2020-04-02
      </h4>
      <h3>
        Chapter&nbsp;5.&nbsp;File Systems and Disk Management
      </h3>
      <ul>
        <li class="prev">
          <a accesskey="p" href="filesystems.html" title=
          "File Systems and Disk Management">Prev</a>
          <p>
            File Systems and Disk Management
          </p>
        </li>
        <li class="next">
          <a accesskey="n" href="btrfs-progs.html" title=
          "btrfs-progs-5.4.1">Next</a>
          <p>
            btrfs-progs-5.4.1
          </p>
        </li>
        <li class="up">
          <a accesskey="u" href="filesystems.html" title=
          "Chapter&nbsp;5.&nbsp;File Systems and Disk Management">Up</a>
        </li>
        <li class="home">
          <a accesskey="h" href="../index.html" title=
          "Beyond Linux� From Scratch     (System V Edition) - Version 2020-04-02">
          Home</a>
        </li>
      </ul>
    </div>
    <div class="sect1" lang="en" xml:lang="en">
      <h1 class="sect1">
        <a id="initramfs" name="initramfs"></a>About initramfs
      </h1>
      <p>
        The only purpose of an initramfs is to mount the root filesystem. The
        initramfs is a complete set of directories that you would find on a
        normal root filesystem. It is bundled into a single cpio archive and
        compressed with one of several compression algorithms.
      </p>
      <p>
        At boot time, the boot loader loads the kernel and the initramfs
        image into memory and starts the kernel. The kernel checks for the
        presence of the initramfs and, if found, mounts it as / and runs
        /init. The init program is typically a shell script. Note that the
        boot process takes longer, possibly significantly longer, if an
        initramfs is used.
      </p>
      <p>
        For most distributions, kernel modules are the biggest reason to have
        an initramfs. In a general distribution, there are many unknowns such
        as file system types and disk layouts. In a way, this is the opposite
        of LFS where the system capabilities and layout are known and a
        custom kernel is normally built. In this situation, an initramfs is
        rarely needed.
      </p>
      <p>
        There are only four primary reasons to have an initramfs in the LFS
        environment: loading the rootfs from a network, loading it from an
        LVM logical volume, having an encrypted rootfs where a password is
        required, or for the convenience of specifying the rootfs as a LABEL
        or UUID. Anything else usually means that the kernel was not
        configured properly.
      </p>
      <div class="sect2" lang="en" xml:lang="en">
        <h2 class="sect2">
          <a id="initramfs-build" name="initramfs-build"></a>Building an
          initramfs
        </h2>
        <p>
          If you do decide to build an initramfs, the following scripts will
          provide a basis to do it. The scripts will allow specifying a
          rootfs via partition UUID or partition LABEL or a rootfs on an LVM
          logical volume. They do not support an encrypted root file system
          or mounting the rootfs over a network card. For a more complete
          capability see <a class="ulink" href=
          "http://www.linuxfromscratch.org/hints/read.html">the LFS Hints</a>
          or <a class="ulink" href=
          "http://fedoraproject.org/wiki/Dracut">dracut</a>.
        </p>
        <p>
          To install these scripts, run the following commands as the
          <code class="systemitem">root</code> user:
        </p>
        <pre class="root">
<kbd class="command">cat &gt; /sbin/mkinitramfs &lt;&lt; "EOF"
<code class="literal">#!/bin/bash
# This file based in part on the mkinitramfs script for the LFS LiveCD
# written by Alexander E. Patrakov and Jeremy Huntwork.

copy()
{
  local file

  if [ "$2" == "lib" ]; then
    file=$(PATH=/lib:/usr/lib type -p $1)
  else
    file=$(type -p $1)
  fi

  if [ -n "$file" ] ; then
    cp $file $WDIR/$2
  else
    echo "Missing required file: $1 for directory $2"
    rm -rf $WDIR
    exit 1
  fi
}

if [ -z $1 ] ; then
  INITRAMFS_FILE=initrd.img-no-kmods
else
  KERNEL_VERSION=$1
  INITRAMFS_FILE=initrd.img-$KERNEL_VERSION
fi

if [ -n "$KERNEL_VERSION" ] &amp;&amp; [ ! -d "/lib/modules/$1" ] ; then
  echo "No modules directory named $1"
  exit 1
fi

printf "Creating $INITRAMFS_FILE... "

binfiles="sh cat cp dd killall ls mkdir mknod mount "
binfiles="$binfiles umount sed sleep ln rm uname"
binfiles="$binfiles readlink basename"

# Systemd installs udevadm in /bin. Other udev implementations have it in /sbin
if [ -x /bin/udevadm ] ; then binfiles="$binfiles udevadm"; fi

sbinfiles="modprobe blkid switch_root"

#Optional files and locations
for f in mdadm mdmon udevd udevadm; do
  if [ -x /sbin/$f ] ; then sbinfiles="$sbinfiles $f"; fi
done

unsorted=$(mktemp /tmp/unsorted.XXXXXXXXXX)

DATADIR=/usr/share/mkinitramfs
INITIN=init.in

# Create a temporary working directory
WDIR=$(mktemp -d /tmp/initrd-work.XXXXXXXXXX)

# Create base directory structure
mkdir -p $WDIR/{bin,dev,lib/firmware,run,sbin,sys,proc,usr}
mkdir -p $WDIR/etc/{modprobe.d,udev/rules.d}
touch $WDIR/etc/modprobe.d/modprobe.conf
ln -s lib $WDIR/lib64
ln -s ../bin $WDIR/usr/bin

# Create necessary device nodes
mknod -m 640 $WDIR/dev/console c 5 1
mknod -m 664 $WDIR/dev/null    c 1 3

# Install the udev configuration files
if [ -f /etc/udev/udev.conf ]; then
  cp /etc/udev/udev.conf $WDIR/etc/udev/udev.conf
fi

for file in $(find /etc/udev/rules.d/ -type f) ; do
  cp $file $WDIR/etc/udev/rules.d
done

# Install any firmware present
cp -a /lib/firmware $WDIR/lib

# Copy the RAID configuration file if present
if [ -f /etc/mdadm.conf ] ; then
  cp /etc/mdadm.conf $WDIR/etc
fi

# Install the init file
install -m0755 $DATADIR/$INITIN $WDIR/init

if [  -n "$KERNEL_VERSION" ] ; then
  if [ -x /bin/kmod ] ; then
    binfiles="$binfiles kmod"
  else
    binfiles="$binfiles lsmod"
    sbinfiles="$sbinfiles insmod"
  fi
fi

# Install basic binaries
for f in $binfiles ; do
  if [ -e /bin/$f ]; then d="/bin"; else d="/usr/bin"; fi
  ldd $d/$f | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
  copy $d/$f bin
done

# Add lvm if present
if [ -x /sbin/lvm ] ; then sbinfiles="$sbinfiles lvm dmsetup"; fi

for f in $sbinfiles ; do
  ldd /sbin/$f | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
  copy $f sbin
done

# Add udevd libraries if not in /sbin
if [ -x /lib/udev/udevd ] ; then
  ldd /lib/udev/udevd | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
elif [ -x /lib/systemd/systemd-udevd ] ; then
  ldd /lib/systemd/systemd-udevd | sed "s/\t//" | cut -d " " -f1 &gt;&gt; $unsorted
fi

# Add module symlinks if appropriate
if [ -n "$KERNEL_VERSION" ] &amp;&amp; [ -x /bin/kmod ] ; then
  ln -s kmod $WDIR/bin/lsmod
  ln -s kmod $WDIR/bin/insmod
fi

# Add lvm symlinks if appropriate
# Also copy the lvm.conf file
if  [ -x /sbin/lvm ] ; then
  ln -s lvm $WDIR/sbin/lvchange
  ln -s lvm $WDIR/sbin/lvrename
  ln -s lvm $WDIR/sbin/lvextend
  ln -s lvm $WDIR/sbin/lvcreate
  ln -s lvm $WDIR/sbin/lvdisplay
  ln -s lvm $WDIR/sbin/lvscan

  ln -s lvm $WDIR/sbin/pvchange
  ln -s lvm $WDIR/sbin/pvck
  ln -s lvm $WDIR/sbin/pvcreate
  ln -s lvm $WDIR/sbin/pvdisplay
  ln -s lvm $WDIR/sbin/pvscan

  ln -s lvm $WDIR/sbin/vgchange
  ln -s lvm $WDIR/sbin/vgcreate
  ln -s lvm $WDIR/sbin/vgscan
  ln -s lvm $WDIR/sbin/vgrename
  ln -s lvm $WDIR/sbin/vgck
  # Conf file(s)
  cp -a /etc/lvm $WDIR/etc
fi

# Install libraries
sort $unsorted | uniq | while read library ; do
# linux-vdso and linux-gate are pseudo libraries and do not correspond to a file
# libsystemd-shared is in /lib/systemd, so it is not found by copy, and
# it is copied below anyway
  if [[ "$library" == linux-vdso.so.1 ]] ||
     [[ "$library" == linux-gate.so.1 ]] ||
     [[ "$library" == libsystemd-shared* ]]; then
    continue
  fi

  copy $library lib
done

if [ -d /lib/udev ]; then
  cp -a /lib/udev $WDIR/lib
fi
if [ -d /lib/systemd ]; then
  cp -a /lib/systemd $WDIR/lib
fi
if [ -d /lib/elogind ]; then
  cp -a /lib/elogind $WDIR/lib
fi

# Install the kernel modules if requested
if [ -n "$KERNEL_VERSION" ]; then
  find                                                                        \
     /lib/modules/$KERNEL_VERSION/kernel/{crypto,fs,lib}                      \
     /lib/modules/$KERNEL_VERSION/kernel/drivers/{block,ata,md,firewire}      \
     /lib/modules/$KERNEL_VERSION/kernel/drivers/{scsi,message,pcmcia,virtio} \
     /lib/modules/$KERNEL_VERSION/kernel/drivers/usb/{host,storage}           \
     -type f 2&gt; /dev/null | cpio --make-directories -p --quiet $WDIR

  cp /lib/modules/$KERNEL_VERSION/modules.{builtin,order}                     \
            $WDIR/lib/modules/$KERNEL_VERSION

  depmod -b $WDIR $KERNEL_VERSION
fi

( cd $WDIR ; find . | cpio -o -H newc --quiet | gzip -9 ) &gt; $INITRAMFS_FILE

# Prepare early loading of microcode if available
if ls /lib/firmware/intel-ucode/* &gt;/dev/null 2&gt;&amp;1 ||
   ls /lib/firmware/amd-ucode/*   &gt;/dev/null 2&gt;&amp;1; then

# first empty WDIR to reuse it
  rm -r $WDIR/*

  DSTDIR=$WDIR/kernel/x86/microcode
  mkdir -p $DSTDIR

  if [ -d /lib/firmware/amd-ucode ]; then
    cat /lib/firmware/amd-ucode/microcode_amd*.bin &gt; $DSTDIR/AuthenticAMD.bin
  fi

  if [ -d /lib/firmware/intel-ucode ]; then
    cat /lib/firmware/intel-ucode/* &gt; $DSTDIR/GenuineIntel.bin
  fi

  ( cd $WDIR; find . | cpio -o -H newc --quiet ) &gt; microcode.img
  cat microcode.img $INITRAMFS_FILE &gt; tmpfile
  mv tmpfile $INITRAMFS_FILE
  rm microcode.img
fi

# Remove the temporary directories and files
rm -rf $WDIR $unsorted
printf "done.\n"
</code>
EOF

chmod 0755 /sbin/mkinitramfs</kbd>
</pre>
        <pre class="root">
<kbd class="command">mkdir -p /usr/share/mkinitramfs &amp;&amp;
cat &gt; /usr/share/mkinitramfs/init.in &lt;&lt; "EOF"
<code class="literal">#!/bin/sh

PATH=/bin:/usr/bin:/sbin:/usr/sbin
export PATH

problem()
{
   printf "Encountered a problem!\n\nDropping you to a shell.\n\n"
   sh
}

no_device()
{
   printf "The device %s, which is supposed to contain the\n" $1
   printf "root file system, does not exist.\n"
   printf "Please fix this problem and exit this shell.\n\n"
}

no_mount()
{
   printf "Could not mount device %s\n" $1
   printf "Sleeping forever. Please reboot and fix the kernel command line.\n\n"
   printf "Maybe the device is formatted with an unsupported file system?\n\n"
   printf "Or maybe filesystem type autodetection went wrong, in which case\n"
   printf "you should add the rootfstype=... parameter to the kernel command line.\n\n"
   printf "Available partitions:\n"
}

do_mount_root()
{
   mkdir /.root
   [ -n "$rootflags" ] &amp;&amp; rootflags="$rootflags,"
   rootflags="$rootflags$ro"

   case "$root" in
      /dev/* ) device=$root ;;
      UUID=* ) eval $root; device="/dev/disk/by-uuid/$UUID"  ;;
      LABEL=*) eval $root; device="/dev/disk/by-label/$LABEL" ;;
      ""     ) echo "No root device specified." ; problem    ;;
   esac

   while [ ! -b "$device" ] ; do
       no_device $device
       problem
   done

   if ! mount -n -t "$rootfstype" -o "$rootflags" "$device" /.root ; then
       no_mount $device
       cat /proc/partitions
       while true ; do sleep 10000 ; done
   else
       echo "Successfully mounted device $root"
   fi
}

do_try_resume()
{
   case "$resume" in
      UUID=* ) eval $resume; resume="/dev/disk/by-uuid/$UUID"  ;;
      LABEL=*) eval $resume; resume="/dev/disk/by-label/$LABEL" ;;
   esac

   if $noresume || ! [ -b "$resume" ]; then return; fi

   ls -lH "$resume" | ( read x x x x maj min x
       echo -n ${maj%,}:$min &gt; /sys/power/resume )
}

init=/sbin/init
root=
rootdelay=
rootfstype=auto
ro="ro"
rootflags=
device=
resume=
noresume=false

mount -n -t devtmpfs devtmpfs /dev
mount -n -t proc     proc     /proc
mount -n -t sysfs    sysfs    /sys
mount -n -t tmpfs    tmpfs    /run

read -r cmdline &lt; /proc/cmdline

for param in $cmdline ; do
  case $param in
    init=*      ) init=${param#init=}             ;;
    root=*      ) root=${param#root=}             ;;
    rootdelay=* ) rootdelay=${param#rootdelay=}   ;;
    rootfstype=*) rootfstype=${param#rootfstype=} ;;
    rootflags=* ) rootflags=${param#rootflags=}   ;;
    resume=*    ) resume=${param#resume=}         ;;
    noresume    ) noresume=true                   ;;
    ro          ) ro="ro"                         ;;
    rw          ) ro="rw"                         ;;
  esac
done

# udevd location depends on version
if [ -x /sbin/udevd ]; then
  UDEVD=/sbin/udevd
elif [ -x /lib/udev/udevd ]; then
  UDEVD=/lib/udev/udevd
elif [ -x /lib/systemd/systemd-udevd ]; then
  UDEVD=/lib/systemd/systemd-udevd
else
  echo "Cannot find udevd nor systemd-udevd"
  problem
fi

${UDEVD} --daemon --resolve-names=never
udevadm trigger
udevadm settle

if [ -f /etc/mdadm.conf ] ; then mdadm -As                       ; fi
if [ -x /sbin/vgchange  ] ; then /sbin/vgchange -a y &gt; /dev/null ; fi
if [ -n "$rootdelay"    ] ; then sleep "$rootdelay"              ; fi

do_try_resume # This function will not return if resuming from disk
do_mount_root

killall -w ${UDEVD##*/}

exec switch_root /.root "$init" "$@"
</code>
EOF</kbd>
</pre>
      </div>
      <div class="sect2" lang="en" xml:lang="en">
        <h2 class="sect2">
          <a id="initramfs-install" name="initramfs-install"></a>Using an
          initramfs
        </h2>
        <h3>
          Required Runtime Dependency
        </h3>
        <p class="required">
          <a class="xref" href="../general/cpio.html" title=
          "cpio-2.13">cpio-2.13</a>
        </p>
        <h3>
          Other Runtime Dependencies
        </h3>
        <p class="optional">
          <a class="xref" href="lvm2.html" title=
          "LVM2-2.03.09">LVM2-2.03.09</a> and/or <a class="xref" href=
          "mdadm.html" title="mdadm-4.1">mdadm-4.1</a> must be installed
          before generating the initramfs, if the system partition uses them.
        </p>
        <p class="usernotes">
          User Notes: <a class="ulink" href=
          "http://wiki.linuxfromscratch.org/blfs/wiki/initramfs">http://wiki.linuxfromscratch.org/blfs/wiki/initramfs</a>
        </p>
        <p>
          To build an initramfs, run the following as the <code class=
          "systemitem">root</code> user:
        </p>
        <pre class="userinput">
<kbd class="command">mkinitramfs [KERNEL VERSION]</kbd>
</pre>
        <p>
          The optional argument is the directory where the appropriate kernel
          modules are located. This must be a subdirectory of <code class=
          "filename">/lib/modules</code>. If no modules are specified, then
          the initramfs is named <span class=
          "emphasis"><em>initrd.img-no-kmods</em></span>. If a kernel version
          is specified, the initrd is named <span class=
          "emphasis"><em>initrd.img-$KERNEL_VERSION</em></span> and is only
          appropriate for the specific kernel specified. The output file will
          be placed in the current directory.
        </p>
        <p>
          If early loading of microcode is needed (see <a class="xref" href=
          "firmware.html#cpu-microcode" title=
          "Microcode updates for CPUs">the section called &ldquo;Microcode
          updates for CPUs&rdquo;</a>), you can install the appropriate blob
          or container in <code class="filename">/lib/firmware</code>. It
          will be automatically added to the initrd when running <span class=
          "command"><strong>mkinitramfs</strong></span>.
        </p>
        <p>
          After generating the initrd, copy it to the <code class=
          "filename">/boot</code> directory.
        </p>
        <p>
          Now edit <code class="filename">/boot/grub/grub.cfg</code> and add
          a new menuentry. Below are several examples.
        </p>
        <pre class="userinput">
<kbd class="command"># Generic initramfs and root fs identified by UUID
menuentry "LFS Dev (LFS-7.0-Feb14) initrd, Linux 3.0.4"
{
  linux  /vmlinuz-3.0.4-lfs-20120214 root=UUID=54b934a9-302d-415e-ac11-4988408eb0a8 ro
  initrd /initrd.img-no-kmods
}</kbd>
</pre>
        <pre class="userinput">
<kbd class="command"># Generic initramfs and root fs on LVM partition
menuentry "LFS Dev (LFS-7.0-Feb18) initrd lvm, Linux 3.0.4"
{
  linux  /vmlinuz-3.0.4-lfs-20120218 root=/dev/mapper/myroot ro
  initrd /initrd.img-no-kmods
}</kbd>
</pre>
        <pre class="userinput">
<kbd class="command"># Specific initramfs and root fs identified by LABEL
menuentry "LFS Dev (LFS-7.1-Feb20) initrd label, Linux 3.2.6"
{
  linux  /vmlinuz-3.2.6-lfs71-120220 root=LABEL=lfs71 ro
  initrd /initrd.img-3.2.6-lfs71-120220
}</kbd>
</pre>
        <p>
          Finally, reboot the system and select the desired system.
        </p>
      </div>
      <p class="updated">
        Last updated on 2020-03-25 16:46:27 -0500
      </p>
    </div>
    <div class="navfooter">
      <ul>
        <li class="prev">
          <a accesskey="p" href="filesystems.html" title=
          "File Systems and Disk Management">Prev</a>
          <p>
            File Systems and Disk Management
          </p>
        </li>
        <li class="next">
          <a accesskey="n" href="btrfs-progs.html" title=
          "btrfs-progs-5.4.1">Next</a>
          <p>
            btrfs-progs-5.4.1
          </p>
        </li>
        <li class="up">
          <a accesskey="u" href="filesystems.html" title=
          "Chapter&nbsp;5.&nbsp;File Systems and Disk Management">Up</a>
        </li>
        <li class="home">
          <a accesskey="h" href="../index.html" title=
          "Beyond Linux� From Scratch     (System V Edition) - Version 2020-04-02">
          Home</a>
        </li>
      </ul>
    </div>
  </body>
</html>
